<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>typeScript面试题</title>
    <link rel="stylesheet" href="../1style/index.css"/>
    <script src="../1style/jquery.js"></script>
</head>
<body>
<h1>typeScript面试题</h1>

<h3>javaScript(js)和typeScript(ts)的对比</h3>
<div>
    <pre>
        @:  http://www.zyiz.net/tech/detail-132499.html
        @:  https://segmentfault.com/a/1190000010969537
        @:  https://juejin.cn/post/6926794697553739784 // TypeScript 高级用法
        @:  https://juejin.cn/post/6872111128135073806 // 一份不可多得的TS学习指南
        @:  https://www.typescriptlang.org/zh/play 对比网址
        js  1,解释型弱类型语言 2.js解析引擎可以直接执行 3.存在浏览器兼容性问题
        ts  1.编译型强类型语言 2.编译成js再运行  3.支持语言新特性 4.适合大型项目,
            5.类型提示/约束,更适合团队开发,避免潜在的bug风险,减少沟通成本
    </pre>
</div>

<h3>typeScript中包含js中的6种类型声明外,还有什么类型?</h3>
<div>
    <pre>
    boolean/number/string/symbol/array/enum/any/unknown/tuple/void/null-undefined/object-Object-{}/Never
	never 类型表示的是那些永不存在的值的类型,即使 any 也不可以赋值给 never
	类型声明的首字母不区分大小写，即let num: number = 1等同于let num: Number = 1，推荐小写形式
        // 这些值也是合法的数字类型
    let nan: number = NaN;
    let max: number = Infinity;
    let min: number = -Infinity;
    let never: never;
    never = undefined; // 但即使never === undefined，赋值逻辑仍然会报错
    元组Tuple，跟数组的差别主要体现在：元组的长度是固定已知的。因此使用场景也非常明确
    </pre>
</div>

<h3>void 和 any 和 unknown</h3>
<div>
    <pre>
        void 表示没有任何类型（可以被赋值为 null 和 undefined）
        void 类型像是与 any 类型相反，没有任何类型。函数没有返回值时，你通常会见到其返回值类型是 void：
        TypeScript 3.0 引入了一个顶级的 unknown 类型,any 就是放弃了任何类型检查,
        unknown 比 any 更安全, 不进行类型断言,使用的时候报错 https://cloud.tencent.com/developer/article/1794738
        https://blog.csdn.net/lihui61357457/article/details/125167464
    </pre>
</div>

<h3>web前端-TypeScript的一些优点</h3>
<div>
    <pre>
        ts就是Type-Script,重点就是在type,类型检测上
        声明和使用变量时候,不用类型推导的情况下,指定其类型,可以避免在使用中遇到bug,
        无需运行程序即可修复潜在bug.
        比如后台反馈data中的list,前端使用list.length 有是有bug的
        同时也支持 ES 6,ES 7
    </pre>
</div>
<h3>Object/object/{}三者之间的执行结果完全不同。</h3>
<div>
    <pre>
        Object变量值可以是任意值，如字符串/数字/数组/函数等，但是如果变量值不是对象，则无法使用其变量值特有的方法，如let list: Object = []不会报错，但执行list.push(1)会报错。造成这种情况的原因是因为在Javascript中，在当前对象的原型链上找不到属性/方法时，会向上一层对象进行查找，而Object.prototype是所有对象原型链查找的终点，也因此在Typescript中将类型声明成Object不会报错，但无法使用非对象的属性/方法
        以object变量值只能是对象，其他值会报错。值得注意的是，object声明的对象无法访问/添加对象上的任何属性/方法，实际效果类似于通过Object.create(null)创建的空对象，暂时不知道这么设计的原因
        {}其实就是匿名形式的type，因此支持通过 & | 操作符对类型声明进行扩展（即交叉类型和联合类型）
    </pre>
</div>

<h3>Array类型的定义</h3>
<div>
    <pre>
        let list: number[] = [1, 2, 3]; // ES5：var list = [1,2,3];
        let list: Array＜number＞ = [1, 2, 3]; // Array＜number＞泛型语法
        Array是唯一的泛型类型，也是唯一有两种不同的写法：Array＜T＞和T[]。
    </pre>
</div>


<h3>Null 和 Undefined 类型 ! 感叹号</h3>
<div>
    <pre>
        你可以使用类型断言手动去除。 语法是添加!后缀：identifier!从identifier的类型里去除了null和undefined：
        function fixed(name: string | null): string {
          function postfix(epithet: string) {
            return (name!).charAt(0) + '.  the ' + epithet; // ok
          }
          name = name || "Bob";
          return postfix("great");
        }
    </pre>
</div>

<h3>typeScript类型守卫</h3>
<div>
    <pre>
        运行时检查的一种表达式，用于确保该类型在一定的范围内,思想是尝试检测属性、方法或原型，以确定如何处理值。目前主要有四种的方式来实现类型保护
        in 关键字。typeof 关键字。instanceof 关键字。 自定义类型保护的类型谓词
    </pre>
</div>

<h3>联合类型 |,交叉类型 &</h3>
<div>
    <pre>
        交叉类型: 将多个类型合并为一个类型。同名基础类型属性的合并 同名非基础类型属性的合并

        type Form1Type = { name: string; } & { gender: number; }
        // 等于 type Form1Type = { name: string; gender: number; }
        type Form2Type = { name: string; } | { gender: number; }
        // 等于 type Form2Type = { name?: string; gender?: number; }

        let form1: Form1Type = { name: '王五' } // 提示缺少gender参数
        let form2: Form2Type = { name: '刘六' } // 验证通过

        type Form3Type = { name: string; } & { name?: string; gender: number; }
        // 等于 type Form3Type = { name: string; gender: number; }
        type Form4Type = { name: string; } | { name?: string; gender: number; }
        // 等于 type Form4Type = { name?: string; gender: number; }

        let form3: Form3Type = { gender: 1 } // 提示缺少name参数
        let form4: Form4Type = { gender: 1 } // 验证通过

        type Form5Type = { name: string; } & { name?: number; gender: number; }
        // 等于 type Form5Type = { name: never; gender: number; }
        type Form6Type = { name: string; } | { name?: number; gender: number; }
        // 等于 type Form6Type = { name?: string | number; gender: number; }

        let form5: Form5Type = { name: '张三', gender: 1 } // 提示name的类型为never，不能进行赋值
        let form6: Form6Type = { name: '张三', gender: 1 } // 验证通过
    </pre>
</div>

<h3>typeScript函数类型,可选参数及默认参数,剩余参数</h3>
<div>
    <pre>
    </pre>
</div>

<h3>typeScript函数重载</h3>
<div>
    <pre>
        函数重载或方法重载是使用相同名称和不同参数数量或类型创建多个方法的一种能力。
        function add(a: number, b: number): number;
        function add(a: string, b: string): string;
        function add(a: string, b: number): string;
        function add(a: number, b: string): string;
        function add(a: Combinable, b: Combinable) {
          // type Combinable = string | number;
          if (typeof a === 'string' || typeof b === 'string') {
            return a.toString() + b.toString();
          }
          return a + b;
        }
    </pre>
</div>

<h3>typeScript数组/对象解构,数组/对象展开运算符</h3>
<div>
    <pre></pre>
</div>

<h3>泛型</h3>
<div>
    <pre>
        定义函数、接口或类的时候，不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
        interface Lengthwise {length: number;}

        function loggingIdentity＜T extends Lengthwise＞(arg: T): T {
            console.log(arg.length); // 如果不约束一下 这里是会报错
            return arg;
        }
        loggingIdentity(7);
        T 代表 Type　K（Key）：表示对象中的键类型；　V（Value）：表示对象中的值类型；E（Element）：表示元素类型。U，用于扩展我们定义的 identity 函数
        泛型工具类型　type Func = （typeof）1. toArray　2.keyof　3.in  4.infer  5.extends  6.Partial
    </pre>
</div>

<h3>接口</h3>
<div>
    <pre>
        接口是一个很重要的概念，它是对行为的抽象
        interface Person {name: string;}
    </pre>
</div>

<h3>装饰器是什么</h3>
<div>
    <pre>
        接口是一个很重要的概念，它是对行为的抽象
        interface Person {name: string;}
    </pre>
</div>


</body>
</html>

<script>
  $(function () {
    $("h3").click(function () {
      $(this).next().toggle();
    });
  })
</script>

